#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>

// sdl初始化并创建窗口
bool init();

// 加载图片
bool loadMedia();

// 关闭sdl并释放资源
void close();

// Loads individual image as texture
SDL_Texture* loadTexture( std::string path );

// 渲染的窗口
SDL_Window * gWindow = nullptr;

// 当我们处理 SDL 纹理时，需要一个 SDL_Renderer 将其渲染到屏幕上
//The window renderer
SDL_Renderer* gRenderer = nullptr;

//当前展示的texture
SDL_Texture* gTexture = nullptr;

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

bool init()
{
     //Initialization flag
    bool success = true;

    //Initialize SDL
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        char str[1024];
        sprintf(str, "SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
        std::cout << str << std::endl;
        success = false;
    }
    else
    {
        //Create window
        gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
        if( gWindow == nullptr )
        {
            char str[1024];
            sprintf(str, "Window could not be created! SDL_Error: %s\n", SDL_GetError());
            std::cout << str << std::endl;
            success = false;
        }
        else
        {
            //Create renderer for window
            gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );
            if( gRenderer == nullptr )
            {
                std::cout << "Renderer could not be created! SDL Error:" << SDL_GetError() << std::endl;
                success = false;
            }
            else
            {
                //Initialize renderer color
                SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );

                //Initialize PNG loading
                int imgFlags = IMG_INIT_PNG;
                if( !( IMG_Init( imgFlags ) & imgFlags ) )
                {
                    std::cout << "SDL_image could not initialize! SDL_image Error:" << IMG_GetError() << std::endl;
                    success = false;
                }
            }
        }
    }

    return success;
}

SDL_Texture* loadTexture( std::string path )
{
    //The final texture
    SDL_Texture* newTexture = nullptr;

    //Load image at specified path
    SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
    if( loadedSurface == nullptr )
    {
        char str[1024];
        sprintf(str, "Unable to load image %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
        std::cout << str << std::endl;
    }
    else
    {
        //Create texture from surface pixels
        newTexture = SDL_CreateTextureFromSurface( gRenderer, loadedSurface );
        if( newTexture == nullptr )
        {
            char str[1024];
            sprintf(str, "Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
            std::cout << str << std::endl;
        }

        //Get rid of old loaded surface
        SDL_FreeSurface( loadedSurface );
    }

    return newTexture;
}

bool loadMedia()
{
    //Loading success flag
    bool success = true;

    //Load png texture
    gTexture = loadTexture( "preview.png" );
    if( gTexture == nullptr )
    {
        std::cout << "Failed to load texture image!" << std::endl;
        success = false;
    }

    return success;
}

void close()
{
    // 释放资源  

    //Free loaded image
    SDL_DestroyTexture( gTexture );
    gTexture = nullptr;

    //Destroy window
    SDL_DestroyRenderer( gRenderer );
    SDL_DestroyWindow( gWindow );
    gRenderer = nullptr;
    gWindow = nullptr;

    //Quit SDL subsystems
    IMG_Quit();
    SDL_Quit();
}


int main( int argc, char* args[] )
{
    //Start up SDL and create window
    if( !init() )
    {
        std::cout << "Failed to initialize!" << std::endl;
    }
    else
    {
        //Load media
        if( !loadMedia() )
        {
            std::cout << "Failed to load media!" << std::endl;
        }
        else
        {
            //Hack to get window to stay up
            SDL_Event e; 
            bool quit = false; 

            //While application is running
            while( !quit )
            {
                //Handle events on queue
                while( SDL_PollEvent( &e ) != 0 )
                {
                    //User requests quit
                    if( e.type == SDL_QUIT )
                    {
                        quit = true;
                    }
                }
                //Clear screen  该函数将用上次通过 SDL_SetRenderDrawColor 设置的颜色填充屏幕。
                SDL_RenderClear( gRenderer );

                //Render texture to screen 
                /*使用 SDL_RenderCopy 渲染纹理。渲染纹理后，需更新屏幕，但由于没有使用 SDL_Surfaces 进行渲染，因此无法使用 SDL_UpdateWindowSurface
                必须使用 SDL_RenderPresent*/
                SDL_RenderCopy( gRenderer, gTexture, NULL, NULL );

                //Update screen
                SDL_RenderPresent( gRenderer );
            }
        }
    }

    //Free resources and close SDL
    close();

    return 0;
}


